import numpy as np
import matplotlib.pyplot as plt

plt.rcParams['font.sans-serif'] = ['SimHei']  # 用黑体显示中文
plt.rcParams['axes.unicode_minus'] = False    # 正常显示负号

# 简化的分式线性变换类
class LinearFractionalTransformation:
    def __init__(self, a, b, c, d):
        self.a, self.b, self.c, self.d = a, b, c, d
        if abs(a*d - b*c) < 1e-10:
            raise ValueError("ad-bc不能为0")
    
    def transform(self, z):
        return (self.a * z + self.b) / (self.c * z + self.d)
    
    def find_fixed_points(self):
        if abs(self.c) < 1e-10:
            return [self.b / (self.d - self.a)] if abs(self.d - self.a) > 1e-10 else [np.inf]
        # 解 c*z^2 + (d-a)*z - b = 0
        a_coeff, b_coeff, c_coeff = self.c, self.d - self.a, -self.b
        discriminant = b_coeff**2 - 4*a_coeff*c_coeff
        sqrt_disc = np.sqrt(discriminant)
        return [(-b_coeff + sqrt_disc) / (2*a_coeff), (-b_coeff - sqrt_disc) / (2*a_coeff)]

# 求将 0, i, -i 变为 1, -1, 0 的变换
def find_transformation(z1, z2, z3, w1, w2, w3):
    def transformation(z):
        numerator = ((z2-z3)*(z1-z)*w1 + (z3-z1)*(z2-z)*w2 + (z1-z2)*(z3-z)*w3)
        denominator = ((z2-z3)*(z1-z) + (z3-z1)*(z2-z) + (z1-z2)*(z3-z))
        return numerator / denominator if abs(denominator) > 1e-12 else np.inf
    return transformation

# 实验代码
print("实验一：分式线性变换")
z_points, w_points = [0, 1j, -1j], [1, -1, 0]
trans_func = find_transformation(z_points[0], z_points[1], z_points[2], w_points[0], w_points[1], w_points[2])

print("验证变换:")
for i in range(len(z_points)):
    result = trans_func(z_points[i])
    print(f"z={z_points[i]} -> w={result:.4f}, 期望={w_points[i]}")

# 可视化点变换
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 5))
ax1.scatter([0, 0, 0], [0, 1, -1], color=['red', 'blue', 'green'], s=100, label=['z=0', 'z=i', 'z=-i'])
ax1.set_xlim(-2, 2); ax1.set_ylim(-2, 2); ax1.set_title('原始点'); ax1.grid(True); ax1.legend()
ax2.scatter([1, -1, 0], [0, 0, 0], color=['red', 'blue', 'green'], s=100, label=['w=1', 'w=-1', 'w=0'])
ax2.set_xlim(-2, 2); ax2.set_ylim(-2, 2); ax2.set_title('变换后的点'); ax2.grid(True); ax2.legend()
plt.tight_layout(); plt.show()

# 分析习题8的变换
print("\n分析分式线性变换的不动点:")
transforms = [
    (LinearFractionalTransformation(1, 0, 2, -1), "(1) w = z/(2z-1)"),
    (LinearFractionalTransformation(2, 0, 3, -1), "(2) w = 2z/(3z-1)"),
    (LinearFractionalTransformation(3, -4, 1, -1), "(3) w = (3z-4)/(z-1)"),
    (LinearFractionalTransformation(1, 0, -1, 2), "(4) w = z/(2-z)")
]

for transform, name in transforms:
    fixed_points = transform.find_fixed_points()
    print(f"{name}: 不动点 {fixed_points}")